<template>
  <div class="steve-textarea">
    <div v-if="aceButtonVisible" class="editor">
      <t-button size="small" @click="onOpenDialog">
        <steve-icon name="code" />
      </t-button>
    </div>
    <t-textarea v-model="textValue" :autosize="true" @change="onQueryRules" />
    <steve-dialog-ace-editor
      v-if="aceButtonVisible"
      v-model:visible="aceVisible"
      :value="aceValue"
      @confirm="onDialogAceConfirm"
    />
  </div>
</template>

<script setup lang="ts">
import { isJSON } from 'validator';
import { ref, watch } from 'vue';

import SteveDialogAceEditor from '@/components/steveDialogAceEditor/index.vue';
import SteveIcon from '@/components/steveIcon/index.vue';

const props = defineProps({
  value: {
    type: String,
    default: '',
  },
});

const emit = defineEmits(['update:value']);
const textValue = ref(props.value);
watch(textValue, (v) => {
  emit('update:value', v);
});

watch(
  () => props.value,
  (v) => {
    textValue.value = v;
    onQueryRules();
  },
);

// 打开ACE编辑器
const aceVisible = ref(false);
const aceButtonVisible = ref(false);
const aceValue = ref('');

// Dialog确认事件
const onDialogAceConfirm = (v: any) => {
  let value = '';
  if (currentRegex.value.type === 0) {
    value = `@js:\n${v}`;
  } else if (currentRegex.value.type === 1) {
    value = `<js>\n${v}\n</js>`;
  } else {
    value = v;
  }

  if (currentRegex.value.regex) {
    textValue.value = textValue.value.replace(currentRegex.value.regex, value);
  } else {
    textValue.value = value;
  }
  aceVisible.value = false;
};

// 打开Dialog
const onOpenDialog = () => {
  if (currentRegex.value) {
    if (currentRegex.value.type === 2) {
      aceValue.value = textValue.value;
    } else {
      const match = textValue.value.match(currentRegex.value.regex);
      if (match !== null) {
        aceValue.value = `${match[1]}`.trim();
      }
    }
  }
  aceVisible.value = true;
};

// 规则
const regexArr = ref([
  {
    name: '前缀JS',
    type: 0,
    regex: /@js:([\s\S]*?)$/,
  },
  {
    name: '标签JS',
    type: 1,
    regex: /<js>([\s\S]*?)<\/js>/,
  },
  {
    name: 'json',
    type: 2,
    regex: null,
  },
]);
// 当前使用的规则
const currentRegex = ref({
  name: '',
  type: 0,
  regex: null,
});

// 查询是否在规则内
const onQueryRules = () => {
  aceButtonVisible.value = false;
  for (const regex of regexArr.value) {
    if (regex.type !== 2 && regex.regex) {
      if (new RegExp(regex.regex).test(textValue.value)) {
        currentRegex.value = regex;
        aceButtonVisible.value = true;
        break;
      }
    } else {
      if (isJSON(textValue.value)) {
        currentRegex.value = regex;
        aceButtonVisible.value = true;
        break;
      }
    }
  }
};
onQueryRules();
</script>

<style lang="less" scoped>
.steve-textarea {
  position: relative;
  width: 100%;

  .editor {
    position: absolute;
    right: 5px;
    z-index: 1;
    top: 5px;
    opacity: 0.5;

    &:hover {
      opacity: 1;
    }
  }
}
</style>
